package yartiss.engine.simulation.scheduling.policies.fp;

import java.util.HashMap;
import java.util.Map;
import java.util.SortedSet;

import yartiss.engine.simulation.Event;
import yartiss.engine.simulation.IEnergyProfile;
import yartiss.engine.simulation.ISchedulingPolicy;
import yartiss.engine.simulation.events.EventGenerator;
import yartiss.engine.simulation.scheduling.policies.AbstractMonoProcessorSchedulingPolicy;
import yartiss.engine.simulation.scheduling.policies.tools.FPSlackTimeManager;
import yartiss.engine.simulation.system.ITask;
import yartiss.engine.simulation.system.ITaskSet;
import yartiss.engine.simulation.system.taskset.TaskSetFactory;

public class FPLSchedulingPolicy extends AbstractMonoProcessorSchedulingPolicy{
	
	private FPSlackTimeManager slackTimeManager = new FPSlackTimeManager();
	
	@Override
	public String getPolicyName() {
		return "FPL";
	}

	@Override
	public ITaskSet createTaskSet() {
		return TaskSetFactory.getNewInstance("priority");
	}
	
	@Override
	public ISchedulingPolicy newInstance() {
		return new FPLSchedulingPolicy();
	}

	private Map<String, Long> metrics = new HashMap<String, Long>();
	long wakeup = -1;
	
	@Override
	public ITask chooseNextTask(ITaskSet taskSet, IEnergyProfile energyProfile,	long date, EventGenerator evGen) {
		metrics.clear();
		SortedSet<ITask> activeTasks = taskSet.getActiveTasks(date);
		if(!activeTasks.isEmpty()){
			ITask first = activeTasks.first();
			long st = slackTimeManager.getSlackTime(date, taskSet);
			metrics.put(Event.SlackTime, st);	
			//System.out.println(date +" : slack time = "+st +"   ?  st2 = "+toto.getSlackTime(date, taskSet));
			if(st>0){
				evGen.generateEvent("check_energy_state", activeTasks.first(), date + st, null);
				wakeup = date + st;
				return null;
			}
			long hlcet = energyProfile.howLongCanExecute(first);
			if (hlcet <= 0) {
				evGen.generateEvent("energy_failure", activeTasks.first(), date, null);
				return null;
			}
			if (hlcet < activeTasks.first().getRemainingCost())
				evGen.generateEvent("check_energy_state", activeTasks.first(), date + hlcet, null);
			return activeTasks.first();
		}
		return null;
	}
}
